package com.ruoyi.wapp.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.base.BaseEntity;
import com.ruoyi.common.constant.CacheKeyConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.ResultConstants;
import com.ruoyi.common.enums.TradeType;
import com.ruoyi.common.enums.TxnTypeGroup;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.sms.wlwx.client.SmsClientMain;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.email.EmailUtil;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.*;
import com.ruoyi.wapp.controller.base.BaseController;
import com.ruoyi.wapp.controller.base.Result;
import com.ruoyi.wapp.util.MyConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;



@RestController
@RequestMapping("/user")
public class UserController extends BaseController {
    @Autowired
    private IWdyUserService wdyUserService;
    @Autowired
    private IWdyTxnHistoryService wdyTxnHistoryService;
    @Autowired
    private IWdyWithdrawService wdyWithdrawService;
    @Autowired
    private IWdyProductService wdyProductService;
    @Autowired
    private IWdyVcBuyOrderService wdyVcBuyOrderService;
    @Autowired
    private IWdyVcReleaseService wdyVcReleaseService;
    @Autowired
    private IWdyBuyProductService wdyBuyProductService;
    @Autowired
    private IWdyRechargeService wdyRechargeService;

    @Autowired
    private IWdyTradeService wdyTradeService;
    @Autowired
    private IWdyTradeRecordService wdyTradeRecordService;
    @Autowired
    private IWdyDealService wdyDealService;
    @Autowired
    private IWdyTransferService wdyTransferService;

    @Autowired
    private IWdyHuobiTradeService wdyHuobiTradeService;

    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private IWdyShoppingCardService wdyShoppingCardService;
    @Autowired
    private IWdyVcFundAssetDailyProfitService wdyVcFundAssetDailyProfitService;

    @Autowired
    private IWdyConsumeService wdyConsumeService;
    @Autowired
    private IWdyKlineService wdyKlineService;

    @GetMapping("/getUser")
    public Result getUser() {
        QueryWrapper<WdyUser> queryWrapper = new QueryWrapper<>();
        String userId = getOnlineMember().getUserId();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("del_flag", BaseEntity.NOT_DELETED);
        WdyUser user = wdyUserService.getOne(queryWrapper);
//        Map<String, Object> stat = wdyUserService.getReferrerStatistic(user.getUserId(), null, DateUtils.getDate(), new HashMap<>());
        Result ok = Result.ok();
        ok.put("user", user);
//        ok.put("directChildrenCount", stat.get("directChildrenCount"));
//        ok.put("childrenCount", stat.get("childrenCount"));
//        ok.put("teamRecharge", stat.get("teamRecharge"));
//        ok.put("teamBuyProduct", stat.get("teamBuyProduct"));
//        ok.put("directChildrenBuyProductCount", (Long)stat.get("directChildrenBuyProductCount") + (Long)stat.get("buyProductCount"));
//        ok.put("teamBuyProductCount", (Long)stat.get("teamBuyProductCount") + (Long)stat.get("buyProductCount"));
        return ok;
    }
    @GetMapping("/getTeam")
    public Result getTeam() {
        QueryWrapper<WdyUser> queryWrapper = new QueryWrapper<>();
        String userId = getOnlineMember().getUserId();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("del_flag", BaseEntity.NOT_DELETED);
        WdyUser user = wdyUserService.getOne(queryWrapper);
        Map<String, Object> stat = wdyUserService.getReferrerStatistic(user.getUserId(), null, DateUtils.getDate(), new HashMap<>());
        Result ok = Result.ok();
        ok.put("user", user);
        ok.put("directChildrenCount", stat.get("directChildrenCount"));
        ok.put("childrenCount", stat.get("childrenCount"));
        ok.put("teamRecharge", stat.get("teamRecharge"));
        ok.put("teamBuyProduct", stat.get("teamBuyProduct"));
        ok.put("directChildrenBuyProductCount", (Long)stat.get("directChildrenBuyProductCount") + (Long)stat.get("buyProductCount"));
        ok.put("teamBuyProductCount", (Long)stat.get("teamBuyProductCount") + (Long)stat.get("buyProductCount"));
        return ok;
    }
    @GetMapping("/getTxnHistorys")
    public Result getTxnHistorys(Integer typeGroup, Integer pageNum, Integer pageSize) {
        if(pageNum == null) {
            pageNum = MyConstants.CONFIG.PAGE_NUM;
        }
        if(pageSize == null) {
            pageSize = MyConstants.CONFIG.PAGE_SIZE;
        }
        WdyUser wdyUser = getOnlineMember();
        PageHelper.startPage(pageNum, pageSize);
        List<WdyTxnHistory> list = wdyTxnHistoryService.listByGroup(wdyUser.getUserId(), TxnTypeGroup.getByCode(typeGroup));
        PageInfo page = new PageInfo(list);
        page.setList(null);
        return Result.ok().put("page", page).put("list", list);
    }

    @GetMapping("/getTxnHistorysByType")
    public Result getTxnHistorysByType(Integer txnType, Integer pageNum, Integer pageSize) {
        if(pageNum == null) {
            pageNum = MyConstants.CONFIG.PAGE_NUM;
        }
        if(pageSize == null) {
            pageSize = MyConstants.CONFIG.PAGE_SIZE;
        }
        PageHelper.startPage(pageNum, pageSize);
        QueryWrapper<WdyTxnHistory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", getOnlineMember().getUserId());
        queryWrapper.eq("txn_type", txnType);
        queryWrapper.orderByDesc("id");
        List<WdyTxnHistory> list = wdyTxnHistoryService.list(queryWrapper);
        PageInfo page = new PageInfo(list);
        page.setList(null);
        return Result.ok().put("page", page).put("list", list);
    }


    @PostMapping("/recharge")
    public Result recharge(WdyRecharge recharge) {
        recharge.setUserId(getOnlineMember().getUserId());
        Map payData = wdyRechargeService.recharge(recharge);
        Result result = Result.ok();
        result.putAll(payData);
        return result;
    }


    @GetMapping("/getRechargeById")
    public Result getRechargeById(String rechargeId) {
        QueryWrapper<WdyRecharge> query = new QueryWrapper<>();
        query.eq("user_id", getOnlineMember().getUserId());
        query.eq("recharge_id", rechargeId);
        WdyRecharge recharge = wdyRechargeService.getOne(query);
        return Result.ok().put("recharge", recharge);
    }

    @GetMapping("/getRechargeList")
    public Result getRechargeList(Integer pageNum, Integer pageSize) {
        if(pageNum == null) {
            pageNum = MyConstants.CONFIG.PAGE_NUM;
        }
        if(pageSize == null) {
            pageSize = MyConstants.CONFIG.PAGE_SIZE;
        }

        WdyUser wdyUser = getOnlineMember();
        PageHelper.startPage(pageNum, pageSize);
        QueryWrapper<WdyRecharge> query = new QueryWrapper<>();
        query.eq("user_id", wdyUser.getUserId());
//        query.eq("recharge_status", WdyRecharge.STATUS_SUCCESS);
        query.orderByDesc("id");
        List<WdyRecharge> list = wdyRechargeService.list(query);
        PageInfo page = new PageInfo(list);
        page.setList(null);
        return Result.ok().put("page", page).put("list", list);
    }

    @GetMapping("/getWithdraws")
    public Result getWithdraws(Integer withdrawStatus, Integer pageNum, Integer pageSize) {
        if(pageNum == null) {
            pageNum = MyConstants.CONFIG.PAGE_NUM;
        }
        if(pageSize == null) {
            pageSize = MyConstants.CONFIG.PAGE_SIZE;
        }

        WdyUser wdyUser = getOnlineMember();
        PageHelper.startPage(pageNum, pageSize);
        QueryWrapper<WdyWithdraw> query = new QueryWrapper<>();
        query.eq("user_id", wdyUser.getUserId());
        if(withdrawStatus != null) {
            query.eq("withdraw_status", withdrawStatus);
        }
        query.eq("del_flag", BaseEntity.NOT_DELETED);
        query.orderByDesc("id");
        List<WdyWithdraw> list = wdyWithdrawService.list(query);
        PageInfo page = new PageInfo(list);
        page.setList(null);
        return Result.ok().put("page", page).put("list", list);
    }

    @GetMapping("/getWithdraw")
    public Result getWithdraw(String withdrawId) {
        WdyUser wdyUser = getOnlineMember();
        QueryWrapper<WdyWithdraw> query = new QueryWrapper<>();
        query.eq("user_id", wdyUser.getUserId());
        query.eq("withdraw_id", withdrawId);
        query.eq("del_flag", BaseEntity.NOT_DELETED);
        WdyWithdraw withdraw = wdyWithdrawService.getOne(query);
        return Result.ok().put("withdraw", withdraw);
    }
    @GetMapping("/getSetTradePwdSmsCode")
    public Result getSetTradePwdSmsCode() {
        WdyUser wdyUser = getOnlineMember();
        String smsCodeCacheKey = CacheKeyConstants.getTempletString(CacheKeyConstants.SMS_CODE_TPL, wdyUser.getMobilePhone(), MyConstants.SMS_CODE_TYPE.TRADE_PWD);
        String smsCode = (String) redisTemplate.opsForValue().get(smsCodeCacheKey);
        if(StringUtils.isNotEmpty(smsCode)) {
            return Result.error(ResultConstants.FI3002, "验证码未过期");
        }
        smsCode = RandomStringUtils.getNumber(4);
        if(isProdEnv()) {
            String content = String.format(MessageUtils.message("msg.content"), smsCode);
            String result = SMSUtil.sendSms(wdyUser.getMobilePhone(),content);
            if (!"SUCCESS".equals(result)){
                return Result.error(ResultConstants.FI3005,MessageUtils.message("msg.send.error"));
            }
        }
        redisTemplate.opsForValue().set(smsCodeCacheKey, smsCode, MyConstants.CONFIG.SMS_CODE_TIMEOUT, TimeUnit.SECONDS);
        log.info("smsCode:{}", smsCode);
        return Result.ok();
    }

    private void checkTradePwd(String tradePwd, boolean needCode, String code, String codeToken, String smsCode, String mobilePhone) {
        //检查参数合法性
        if(StringUtils.isEmpty(tradePwd)) {
            throw new BusinessException(ResultConstants.FI1000, "交易密码不能为空");
        }
        if(!tradePwd.matches(Constants.TRADE_PWD_PATTERN)) {
            throw new BusinessException(ResultConstants.FI1000, "交易密码格式错误");
        }
        if(needCode && StringUtils.isEmpty(code)) {
            throw new BusinessException(ResultConstants.FI1000, "图形验证码不能为空");
        }
        if(needCode && StringUtils.isEmpty(codeToken)) {
            throw new BusinessException(ResultConstants.FI1000, "图形验证码token不能为空");
        }
        if(StringUtils.isEmpty(smsCode)) {
            throw new BusinessException(ResultConstants.FI1000, "短信验证码不能为空");
        }

        if(needCode) {
            String codeCacheKey = CacheKeyConstants.getTempletString(CacheKeyConstants.CODE_TPL, MyConstants.CODE_TYPE.TRADE_PWD, codeToken);
            String cacheCode = (String) redisTemplate.opsForValue().get(codeCacheKey);
            if(cacheCode == null) {
                throw new BusinessException(ResultConstants.FI3000, "图形验证码已过期");
            }

            if(!cacheCode.equals(code)) {
                throw new BusinessException(ResultConstants.FI3001, "图形验证码错误");
            }
        }

        String smsCodeCacheKey = CacheKeyConstants.getTempletString(CacheKeyConstants.SMS_CODE_TPL, mobilePhone, MyConstants.SMS_CODE_TYPE.TRADE_PWD);
        String cacheSmsCode = (String) redisTemplate.opsForValue().get(smsCodeCacheKey);
        if(isProdEnv() && cacheSmsCode == null) {
            throw new BusinessException(ResultConstants.FI3000, "短信验证码已过期");
        }
        if(isProdEnv() && !cacheSmsCode.equals(smsCode)) {
            throw new BusinessException(ResultConstants.FI3001, "短信验证码错误");
        }
    }

    /**
     * 设置交易密码
     * @param tradePwd 交易密码
     * @param code 图形验证码
     * @param codeToken 图形码证码token
     * @param smsCode 短信验证码
     * @return
     */
    @PostMapping("/setTradePwd")
    public Result setTradePwd(String tradePwd, String code, String codeToken, String smsCode) {
        QueryWrapper<WdyUser> query = new QueryWrapper<>();
        query.eq("user_id", getOnlineMember().getUserId());
        query.eq("del_flag", BaseEntity.NOT_DELETED);
        WdyUser user = wdyUserService.getOne(query);
        String mobilePhone = user.getMobilePhone();
        checkTradePwd(tradePwd, false , code, codeToken, smsCode, mobilePhone);
        if(StringUtils.isNotEmpty(user.getTradePassword())) {
            return Result.error(ResultConstants.FI2001, "交易密码已存在");
        }
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        setpwd(tradePwd, passwordEncoder, user);
        return Result.ok();
    }

    private void setpwd(String tradePwd, BCryptPasswordEncoder passwordEncoder, WdyUser user) {
        WdyUser updateUser = new WdyUser();
        updateUser.setTradePassword(passwordEncoder.encode(tradePwd));
        updateUser.setVersion(user.getVersion());
        QueryWrapper<WdyUser> query = new QueryWrapper<>();
        query.eq("user_id", user.getUserId());
        query.eq("del_flag", BaseEntity.NOT_DELETED);
        if(!wdyUserService.update(updateUser, query)) {
            throw new BusinessException(ResultConstants.FI2007, "系统繁忙，请稍后重试");
        }
    }


    /**
     * 重置交易密码
     * @param oldTradePwd
     * @param tradePwd
     * @param code
     * @param codeToken
     * @param smsCode
     * @return
     */
    @PostMapping("/resetTradePwd")
    public Result resetTradePwd(String oldTradePwd, String tradePwd, String code, String codeToken, String smsCode, Integer forget) {
        QueryWrapper<WdyUser> query = new QueryWrapper<>();
        query.eq("user_id", getOnlineMember().getUserId());
        query.eq("del_flag", BaseEntity.NOT_DELETED);
        WdyUser user = wdyUserService.getOne(query);
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        if(forget == null) {
            forget = 0;
        }
        if(forget.intValue() != 1) {
            if(StringUtils.isEmpty(oldTradePwd)) {
                throw new BusinessException(ResultConstants.FI1000, "旧密码不能为空");
            }
            if(!passwordEncoder.matches(oldTradePwd, user.getTradePassword())) {
                throw new BusinessException(ResultConstants.FI2003, "旧密码错误");
            }
        }
        String mobilePhone = user.getMobilePhone();
        checkTradePwd(tradePwd, false, code, codeToken, smsCode, mobilePhone);
        setpwd(tradePwd, passwordEncoder, user);
        return Result.ok();
    }


    @PostMapping("/withdraw")
    public Result withdraw(WdyWithdraw withdrawData, String code) {
        QueryWrapper<WdyUser> query = new QueryWrapper<>();
        query.eq("user_id", getOnlineMember().getUserId());
        query.eq("del_flag", BaseEntity.NOT_DELETED);
        WdyUser user = wdyUserService.getOne(query);

        if(StringUtils.isEmpty(code)) {
            throw new BusinessException(ResultConstants.FI1000, "code " + MessageUtils.message("not.null"));
        }

        String smsCodeCacheKey = CacheKeyConstants.getTempletString(CacheKeyConstants.SMS_CODE_TPL, user.getUserName(), MyConstants.SMS_CODE_TYPE.WITHDRAW);
        String smsCode = (String) redisTemplate.opsForValue().get(smsCodeCacheKey);
        if(StringUtils.isEmpty(smsCode)) {
            return Result.error(ResultConstants.FI3002, "验证码已过期");
        }
        if(!smsCode.equals(code)) {
            return Result.error(ResultConstants.FI3002, "验证码错误");
        }

        withdrawData.setUserId(user.getUserId());
        wdyWithdrawService.autoWithdraw(withdrawData);
        redisTemplate.delete(smsCodeCacheKey);

        return Result.ok();
    }


    /**
     * 重置密码
     * @param oldPwd
     * @param newPwd
     * @return
     */
    @PostMapping("/resetPwd")
    public Result resetPwd(String oldPwd, String newPwd) {
        QueryWrapper<WdyUser> query = new QueryWrapper<>();
        query.eq("user_id", getOnlineMember().getUserId());
        query.eq("del_flag", BaseEntity.NOT_DELETED);
        WdyUser user = wdyUserService.getOne(query);
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        if(StringUtils.isEmpty(oldPwd)) {
            throw new BusinessException(ResultConstants.FI1000, "oldPwd" + MessageUtils.message("not.null"));
        }
        if(!passwordEncoder.matches(oldPwd, user.getPassword())) {
            throw new BusinessException(ResultConstants.FI2003, MessageUtils.message("msg.oldpwd.error"));
        }
        if(StringUtils.isEmpty(newPwd)) {
            throw new BusinessException(ResultConstants.FI1000, "newPwd" + MessageUtils.message("not.null"));
        }
        if(!newPwd.matches(Constants.PWD_PATTERN)) {
            throw new BusinessException(ResultConstants.FI1000, MessageUtils.message("user.password.not.valid"));
        }
        WdyUser updateUser = new WdyUser();
        updateUser.setPassword(passwordEncoder.encode(newPwd));
        wdyUserService.update(updateUser, query);
        return Result.ok();
    }

    @GetMapping("/getWithdrawCode")
    public Result getWithdrawCode() {
        QueryWrapper<WdyUser> query = new QueryWrapper<>();
        query.eq("user_id", getOnlineMember().getUserId());
        query.eq("del_flag", BaseEntity.NOT_DELETED);
        WdyUser wdyUser = wdyUserService.getOne(query);

        String userName = wdyUser.getUserName();

        String smsCodeCacheKey = CacheKeyConstants.getTempletString(CacheKeyConstants.SMS_CODE_TPL, userName, MyConstants.SMS_CODE_TYPE.WITHDRAW);
        String smsCode = (String) redisTemplate.opsForValue().get(smsCodeCacheKey);
        if(StringUtils.isNotEmpty(smsCode)) {
            return Result.error(ResultConstants.FI3002, "验证码未过期");
        }
        smsCode = RandomStringUtils.getNumber(4);
        String content = String.format(MessageUtils.message("msg.content"), smsCode);
        String result = "";
        if(userName.matches(Constants.MOBILE_PATTERN)) {
            try {
                result = SmsClientMain.getReportResultMsg(userName,content);
                JSONObject jsonObject=JSONObject.parseObject(result);
                if ("0".equals(jsonObject.get("respCode"))) {
                    result = "SUCCESS";
                }
            } catch (Exception e) {
                log.error("发送验证码异常", e);
            }
        } else if(userName.matches(Constants.EMAIL_PATTERN)) {
            result = EmailUtil.sendFromYandex(userName, MessageUtils.message("msg.title"), content);
        }
        if (!"SUCCESS".equals(result)){
            return Result.error(ResultConstants.FI3005,MessageUtils.message("msg.send.error"));
        }
        redisTemplate.opsForValue().set(smsCodeCacheKey, smsCode, MyConstants.CONFIG.SMS_CODE_TIMEOUT, TimeUnit.SECONDS);
        log.info("smsCode:{}", smsCode);
        return Result.ok();
    }

    @PostMapping("/buyProduct")
    public Result buyProduct(Long id) {
//        String userId = getOnlineMember().getUserId();
//        wdyProductService.buyProduct(userId, 1);
        return Result.ok();
    }

    @PostMapping("/buyVc")
    public Result buyVc(WdyVcBuyOrder wdyVcBuyOrder) {
        wdyVcBuyOrder.setUserId(getOnlineMember().getUserId());
        wdyVcBuyOrderService.buyVc(wdyVcBuyOrder);
        return Result.ok();
    }


    @PostMapping("/pickVcAll")
    public Result pickVcAll() {
        wdyVcReleaseService.pickVcAll(getOnlineMember().getUserId());
        return Result.ok();
    }

    @PostMapping("/activeProduct")
    public Result activeProduct(String activeCode) {
        String userId = getOnlineMember().getUserId();
        WdyBuyProduct buyProduct = new WdyBuyProduct();
        buyProduct.setActiveCode(activeCode);
        buyProduct.setUserId(userId);
        wdyBuyProductService.active(buyProduct);
        return Result.ok();
    }

    @GetMapping("/getBuyProductList")
    public Result getBuyProductList() {
        QueryWrapper<WdyBuyProduct> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", getOnlineMember().getUserId());
        queryWrapper.eq("active_state", WdyBuyProduct.YES);
        queryWrapper.orderByDesc("id");
        List<WdyBuyProduct> list = wdyBuyProductService.list(queryWrapper);
        return Result.ok().put("list", list);
    }

    @GetMapping("/getReleaseVcList")
    public Result getReleaseVcList(Long buyProductId) {
        QueryWrapper<WdyBuyProduct> buyProductQuery = new QueryWrapper<>();
        buyProductQuery.eq("id", buyProductId);
        buyProductQuery.eq("user_id", getOnlineMember().getUserId());
        buyProductQuery.eq("active_state", WdyBuyProduct.YES);
        WdyBuyProduct buyProduct = wdyBuyProductService.getOne(buyProductQuery);

        QueryWrapper<WdyVcRelease> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", getOnlineMember().getUserId());
        queryWrapper.eq(buyProductId != null, "txn_id", buyProductId);
        queryWrapper.orderByDesc("id");
        List<WdyVcRelease> list = wdyVcReleaseService.list(queryWrapper);
        return Result.ok().put("buyProduct", buyProduct).put("list", list);
    }

    @GetMapping("/getVcBuyOrderList")
    public Result getVcBuyOrderList(Integer pageNum, Integer pageSize) {
        if(pageNum == null) {
            pageNum = MyConstants.CONFIG.PAGE_NUM;
        }
        if(pageSize == null) {
            pageSize = MyConstants.CONFIG.PAGE_SIZE;
        }
        QueryWrapper<WdyVcBuyOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", getOnlineMember().getUserId());
        queryWrapper.orderByDesc("id");
        PageHelper.startPage(pageNum, pageSize);
        List<WdyVcBuyOrder> list = wdyVcBuyOrderService.list(queryWrapper);
        PageInfo page = new PageInfo(list);
        page.setList(null);
        return Result.ok().put("page", page).put("list", list);
    }

    @PostMapping("/bindEmail")
    public Result bindEmail(String email) {
        if(StringUtils.isEmpty(email)) {
            throw new BusinessException(ResultConstants.FI1000, "email" + MessageUtils.message("not.null"));
        }
        if(!email.matches(Constants.EMAIL_PATTERN)) {
            throw new BusinessException(ResultConstants.FI1000, MessageUtils.message("param.error"));
        }
        String userId = getOnlineMember().getUserId();
        QueryWrapper<WdyUser> updateWrapper = new QueryWrapper<>();
        updateWrapper.eq("user_id", userId);
        WdyUser updateUser = new WdyUser();
        updateUser.setEmail(email);
        wdyUserService.update(updateUser, updateWrapper);
        return Result.ok();
    }

    @PostMapping("/trade")
    public Result trade(WdyTrade trade) {
        trade.setUserId(getOnlineMember().getUserId());
        wdyTradeService.trade(trade);
        Map<String, Object> tradeMap = new HashMap<>();
        tradeMap.put("tradeType", trade.getTradeType());
        tradeMap.put("tradeId", trade.getId());
        redisTemplate.opsForList().leftPush(CacheKeyConstants.TRADE_LIST, tradeMap);
        return Result.ok();
    }

    @PostMapping("/cancelTrade")
    public Result cancelTrade(long tradeId) {
        WdyTrade trade = wdyTradeService.getById(tradeId);
        if(trade == null || trade.getTradeState() != WdyTrade.STATE_TRADE
            || !getOnlineMember().getUserId().equals(trade.getUserId())) {
            throw new BusinessException(ResultConstants.FI1000, "委托单不存在或已成交");
        }
        Map<String, Object> tradeMap = new HashMap<>();
        tradeMap.put("tradeType", TradeType.CANCEL.getCode());
        tradeMap.put("tradeId", tradeId);
        redisTemplate.opsForList().leftPush(CacheKeyConstants.TRADE_LIST, tradeMap);
        return Result.ok();
    }

    @GetMapping("/getTradeList")
    public Result getTradeList(Integer pageNum, Integer pageSize) {
        if(pageNum == null) {
            pageNum = MyConstants.CONFIG.PAGE_NUM;
        }
        if(pageSize == null) {
            pageSize = MyConstants.CONFIG.PAGE_SIZE;
        }
        QueryWrapper<WdyTrade> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", getOnlineMember().getUserId());
        queryWrapper.eq("trade_state", WdyTrade.STATE_TRADE);
        queryWrapper.orderByDesc("id");
        PageHelper.startPage(pageNum, pageSize);
        List<WdyTrade> list = wdyTradeService.list(queryWrapper);
        PageInfo page = new PageInfo(list);
        page.setList(null);
        return Result.ok().put("page", page).put("list", list);
    }

    @GetMapping("/getHistoryTradeList")
    public Result getHistoryTradeList(Integer pageNum, Integer pageSize) {
        if(pageNum == null) {
            pageNum = MyConstants.CONFIG.PAGE_NUM;
        }
        if(pageSize == null) {
            pageSize = MyConstants.CONFIG.PAGE_SIZE;
        }
        QueryWrapper<WdyTrade> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", getOnlineMember().getUserId());
        queryWrapper.in("trade_state", WdyTrade.STATE_FINISH, WdyTrade.STATE_CANCEL);
        queryWrapper.orderByDesc("id");
        PageHelper.startPage(pageNum, pageSize);
        List<WdyTrade> list = wdyTradeService.list(queryWrapper);
        PageInfo page = new PageInfo(list);
        page.setList(null);
        return Result.ok().put("page", page).put("list", list);
    }

    @GetMapping("/getTradeRecordList")
    public Result getTradeRecordList(long tradeId) {
        QueryWrapper<WdyTrade> tradeQuery = new QueryWrapper<>();
        tradeQuery.eq("user_id", getOnlineMember().getUserId());
        tradeQuery.eq("id", tradeId);
        WdyTrade trade = wdyTradeService.getOne(tradeQuery);

        QueryWrapper<WdyTradeRecord> tradeRecordQuery = new QueryWrapper<>();
        tradeRecordQuery.eq("user_id", getOnlineMember().getUserId());
        tradeRecordQuery.eq("trade_id", tradeId);
        tradeRecordQuery.orderByDesc("id");
        List<WdyTradeRecord> list = wdyTradeRecordService.list(tradeRecordQuery);
        if(!CollectionUtils.isEmpty(list)) {
            list.forEach(e -> {
                e.addExtraData("deal", wdyDealService.getById(e.getDealId()));
            });
        }
        return Result.ok().put("trade", trade).put("list", list);
    }

    @PostMapping("/transfer")
    public Result transfer(WdyTransfer wdyTransfer) {
        wdyTransfer.setUserId(getOnlineMember().getUserId());
        wdyTransferService.transfer(wdyTransfer);
        return Result.ok();
    }

    @GetMapping("/getTransferList")
    public Result getTransferList(Integer pageNum, Integer pageSize) {
        if(pageNum == null) {
            pageNum = MyConstants.CONFIG.PAGE_NUM;
        }
        if(pageSize == null) {
            pageSize = MyConstants.CONFIG.PAGE_SIZE;
        }
        QueryWrapper<WdyTransfer> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", getOnlineMember().getUserId());
        queryWrapper.orderByDesc("id");
        PageHelper.startPage(pageNum, pageSize);
        List<WdyTransfer> list = wdyTransferService.list(queryWrapper);
        PageInfo page = new PageInfo(list);
        page.setList(null);
        return Result.ok().put("page", page).put("list", list);
    }
    @PostMapping("/huobi/trade")
    public Result huobiTrade(WdyHuobiTrade huobiTrade) {
        huobiTrade.setUserId(getOnlineMember().getUserId());
        wdyHuobiTradeService.trade(huobiTrade);
        return Result.ok();
    }

    @PostMapping("/huobi/cancelTrade")
    public Result huobiCancelTrade(long id) {
        wdyHuobiTradeService.cancel(id, getOnlineMember().getUserId());
        return Result.ok();
    }

    @GetMapping("/huobi/getTradeList")
    public Result huobiGetTradeList(Integer pageNum, Integer pageSize) {
        if(pageNum == null) {
            pageNum = MyConstants.CONFIG.PAGE_NUM;
        }
        if(pageSize == null) {
            pageSize = MyConstants.CONFIG.PAGE_SIZE;
        }
        QueryWrapper<WdyHuobiTrade> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", getOnlineMember().getUserId());
        queryWrapper.eq("trade_state", WdyHuobiTrade.STATE_TRADE);
        queryWrapper.orderByDesc("id");
        PageHelper.startPage(pageNum, pageSize);
        List<WdyHuobiTrade> list = wdyHuobiTradeService.list(queryWrapper);
        PageInfo page = new PageInfo(list);
        page.setList(null);
        return Result.ok().put("page", page).put("list", list);
    }

    @GetMapping("/huobi/getHistoryTradeList")
    public Result huobiGetHistoryTradeList(Integer pageNum, Integer pageSize) {
        if(pageNum == null) {
            pageNum = MyConstants.CONFIG.PAGE_NUM;
        }
        if(pageSize == null) {
            pageSize = MyConstants.CONFIG.PAGE_SIZE;
        }
        QueryWrapper<WdyHuobiTrade> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", getOnlineMember().getUserId());
        queryWrapper.in("trade_state", WdyHuobiTrade.STATE_FINISH, WdyHuobiTrade.STATE_CANCEL);
        queryWrapper.orderByDesc("id");
        PageHelper.startPage(pageNum, pageSize);
        List<WdyHuobiTrade> list = wdyHuobiTradeService.list(queryWrapper);
        PageInfo page = new PageInfo(list);
        page.setList(null);
        return Result.ok().put("page", page).put("list", list);
    }

    @GetMapping("/huobi/getTradeById")
    public Result huobiGetTradeById(long id) {
        QueryWrapper<WdyHuobiTrade> tradeQuery = new QueryWrapper<>();
        tradeQuery.eq("user_id", getOnlineMember().getUserId());
        tradeQuery.eq("id", id);
        WdyHuobiTrade trade = wdyHuobiTradeService.getOne(tradeQuery);
        return Result.ok().put("trade", trade);
    }

    @GetMapping("/getVcFundAsset")
    public Result getVcFundAsset() {
        BigDecimal dailyProfitRatio = new BigDecimal(sysConfigService.selectConfigByKey("vc_fund_asset_daily_profit_ratio")).multiply(new BigDecimal(100));

        QueryWrapper<WdyUser> userQuery = new QueryWrapper<>();
        String userId = getOnlineMember().getUserId();
        userQuery.eq("user_id", userId);
        WdyUser user = wdyUserService.getOne(userQuery);

        QueryWrapper<WdyVcFundAssetDailyProfit> vcFundProfitQuery = new QueryWrapper<>();
        vcFundProfitQuery.eq("user_id", userId);
        vcFundProfitQuery.eq("grant_date", DateUtils.format(DateUtils.addDays(new Date(), -1), DateUtils.YYYY_MM_DD));
        WdyVcFundAssetDailyProfit vcFundAssetDailyProfit = wdyVcFundAssetDailyProfitService.getOne(vcFundProfitQuery);

        vcFundProfitQuery = new QueryWrapper<>();
        vcFundProfitQuery.select("IFNULL(SUM(profit),0) AS profit");
        vcFundProfitQuery.eq("user_id", userId);
        Map<String, Object> totalProfitMap = wdyVcFundAssetDailyProfitService.getMap(vcFundProfitQuery);
        Result result = Result.ok();
        result.put("vcFundAsset", user.getVcFundAsset());
        result.put("dailyProfitRatio", dailyProfitRatio);
        result.put("latestProfit", vcFundAssetDailyProfit != null ? vcFundAssetDailyProfit.getProfit() : BigDecimal.ZERO);
        result.put("totalProfit", totalProfitMap.get("profit"));
        return result;
    }

    @GetMapping("/getVcFundAssetDailyProfitList")
    public Result getVcFundAssetDailyProfitList(Integer pageNum, Integer pageSize) {
        if(pageNum == null) {
            pageNum = MyConstants.CONFIG.PAGE_NUM;
        }
        if(pageSize == null) {
            pageSize = MyConstants.CONFIG.PAGE_SIZE;
        }
        QueryWrapper<WdyVcFundAssetDailyProfit> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", getOnlineMember().getUserId());
        queryWrapper.orderByDesc("id");
        PageHelper.startPage(pageNum, pageSize);
        List<WdyVcFundAssetDailyProfit> list = wdyVcFundAssetDailyProfitService.list(queryWrapper);
        PageInfo page = new PageInfo(list);
        page.setList(null);
        return Result.ok().put("page", page).put("list", list);
    }

    @GetMapping("/getExRateArray")
    public Result getExRateArray(@RequestHeader("token") String token) {
        BigDecimal amount = wdyShoppingCardService.getAmount(getOnlineMember().getUserId());
        JSONArray array = wdyShoppingCardService.getExRateArray(getOnlineMember().getUserId(), amount);
        BigDecimal price = wdyKlineService.getYestodayPrice();
        return Result.ok().put("array", array).put("amount", amount).put("price", price);
    }

    @PostMapping("/buyShoppingCard")
    public Result buyShoppingCard(@RequestHeader("token") String token, BigDecimal amount, int num) {
        wdyShoppingCardService.buyShoppingCard(getOnlineMember().getUserId(), amount, num);
        return Result.ok();
    }

    @GetMapping("/getShoppingCardList")
    public Result getShoppingCardList(@RequestHeader("token") String token, Integer pageNum, Integer pageSize) {
        if(pageNum == null) {
            pageNum = MyConstants.CONFIG.PAGE_NUM;
        }
        if(pageSize == null) {
            pageSize = MyConstants.CONFIG.PAGE_SIZE;
        }
        QueryWrapper<WdyShoppingCard> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", getOnlineMember().getUserId());
        queryWrapper.orderByDesc("ex_time");
        PageHelper.startPage(pageNum, pageSize);
        List<WdyShoppingCard> list = wdyShoppingCardService.list(queryWrapper);
        PageInfo page = new PageInfo(list);
        page.setList(null);
        return Result.ok().put("page", page).put("list", list);
    }

    @PostMapping("/useShoppingCard")
    public Result useShoppingCard(@RequestHeader("token") String token, long id) {
        UpdateWrapper<WdyShoppingCard> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);
        updateWrapper.eq("user_id", getOnlineMember().getUserId());
        updateWrapper.eq("use_flag", BaseEntity.NO);
        updateWrapper.set("use_flag", BaseEntity.YES);
        if(!wdyShoppingCardService.update(updateWrapper)) {
            throw new BusinessException(ResultConstants.FI1000, "购物卡不存在或已使用");
        }
        return Result.ok();
    }

    @GetMapping("/getConsumeList")
    public Result getConsumeList(@RequestHeader("token") String token, Integer pageNum, Integer pageSize) {
        QueryWrapper<WdyConsume> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", getOnlineMember().getUserId());
        queryWrapper.orderByDesc("id");
        PageHelper.startPage(pageNum, pageSize);
        List<WdyConsume> list = wdyConsumeService.list(queryWrapper);
        PageInfo page = new PageInfo(list);
        page.setList(null);
        return Result.ok().put("page", page).put("list", list);
    }
}
